﻿using AttributeRouting.Web.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using WebTech.Coursework02.Models;
using WebTech.Coursework02.Utilities;

namespace WebTech.Coursework02.Controllers
{

    public class SearchController : ApiController
    {
             

        // GET api/autocomplete

        public IDictionary<int, string> Get(string term)
        {
            using (ExtractionEntities ent = new ExtractionEntities())
            {
                return ent.employees.Where(x => x.first_name.Contains(term) || x.last_name.Contains(term)).ToDictionary(x => x.emp_no, x => string.Format("{0} {1}", x.first_name, x.last_name));
            }
        }

        [POST("api/search/")]
        public Response Post(Request request)
        {            
            IQueryable<GridEmployee> employeeQuery = null;
            System.Func<employee, GridEmployee> secondarySelector = x => new GridEmployee() { emp_no = x.emp_no, first_name = x.first_name, last_name = x.last_name,  gender = x.gender };            
          
            using (ExtractionEntities ent = new ExtractionEntities())
            { 
                IEnumerable<GridEmployee> employees = null;

               SearchCriteria searchTypeEnum;
                Enum.TryParse(request.searchType, out searchTypeEnum);
                if (!string.IsNullOrEmpty(request.searchTerm))
                {
                    string[] splitName = request.searchTerm.Split(' ');
                    string firsName = splitName[0];
                    string lastName = (splitName.Length > 1) ? splitName[1] : string.Empty;
                    string enumText = Utility.GetEnumDescription(searchTypeEnum);

                    // check to see if the search type is the employee name
                    if (searchTypeEnum == SearchCriteria.EmployeeName)
                    {
                        if (splitName.Length > 1)
                        {
                            employees = ent.employees.Where(x => x.first_name.Contains(firsName) && x.last_name.Contains(lastName)).ToList().Select(secondarySelector);
                        }
                        else
                        {
                            employees = ent.employees.Where(x => x.first_name.Contains(firsName) || x.last_name.Contains(firsName)).ToList().Select(secondarySelector);
                        }
                    }
                    else if ((int)searchTypeEnum > 3)
                    {
                        // this search is based on the user's department                       
                        string deptNo = ent.departments.FirstOrDefault(x => x.dept_name == enumText).dept_no;

                        if (splitName.Length > 1)
                        {
                            employees = ent.dept_emp.Where(x => x.dept_no == deptNo).Select(g => g.employee).Where(x => x.first_name.Contains(firsName) && x.last_name.Contains(lastName)).ToList().Select(secondarySelector);
                        }
                        else
                        {
                            employees = ent.dept_emp.Where(x => x.dept_no == deptNo).Select(g => g.employee).Where(x => x.first_name.Contains(firsName) || x.last_name.Contains(firsName)).ToList().Select(secondarySelector);
                        }                        
                    }
                    else if ((int)searchTypeEnum < 1)
                    {
                        // searches for the user based on his gender
                        if (splitName.Length > 1)
                        {
                            employees = ent.employees.Where(x => x.first_name.Contains(firsName) && x.last_name.Contains(lastName) && x.gender == enumText).ToList().Select(secondarySelector);
                        }
                        else
                        {
                            employees = ent.employees.Where(x => x.first_name.Contains(firsName) || x.last_name.Contains(firsName) && x.gender == enumText).ToList().Select(secondarySelector);
                        }
                    }
                }
                else if (searchTypeEnum == SearchCriteria.All)
                {
                    // this conditional searches from all the employees in the database.
                    employees = ent.employees.AsEnumerable().Select(secondarySelector);
                }

                employeeQuery = employees.Skip(request.skip).Take(request.take).AsQueryable();

               // return employeeQuery in the form of a response object
                return new Response(employeeQuery.ToArray(), employees.Count());
            }
        }


      

        [POST("api/search/post/{id}")]
        public HttpResponseMessage Post(int id)
        {           
            HttpRequest _request = HttpContext.Current.Request;
           
            // create a response message to send back
            var response = new HttpResponseMessage();
            employee employeeToUpdate = null;
            try
            {
                // select the employee from the database where the id
                // matches the one passed in at api/employees/id

                using (ExtractionEntities ext = new ExtractionEntities())
                {
                    employeeToUpdate = ext.employees.FirstOrDefault(x => x.emp_no == id);

                    if (employeeToUpdate != null)
                    {
                        // update the employee object handling null values or empty strings
                       
                        employeeToUpdate.last_name = string.IsNullOrEmpty(_request["last_name"]) ? employeeToUpdate.last_name : _request["last_name"];
                        employeeToUpdate.first_name = string.IsNullOrEmpty(_request["first_name"]) ? employeeToUpdate.first_name : _request["first_name"];
                        employeeToUpdate.gender = string.IsNullOrEmpty(_request["gender"]) ? employeeToUpdate.gender : _request["gender"];                        
                        ext.SaveChanges();
                        response.StatusCode = HttpStatusCode.OK;
                    }
                    else
                    {
                        // with some more info.
                        response.StatusCode = HttpStatusCode.InternalServerError;
                        response.Content = new StringContent(string.Format("The employee with id {0} was not found in the database", id.ToString()));
                    }
                }
            }
            catch (Exception ex)
            {
                // something went wrong - possibly a database error. return a
                // 500 server error and send the details of the exception.
                response.StatusCode = HttpStatusCode.InternalServerError;
                response.Content = new StringContent(string.Format("The database updated failed: {0}", ex.Message));
            }

            // return the HTTP Response.
            return response;
        }
    }
}
